package com.scsj.cloud.authority.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import com.scsj.cloud.authority.dao.SysMenuMapper;
import com.scsj.cloud.authority.dao.SysUrlMapper;
import com.scsj.cloud.authority.model.SysUrl;

@Service
public class SysBaseService {

	private final Logger logger=LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	private SysUrlMapper urlMapper;
	
	@Autowired
	private SysMenuMapper menuMapper;
	
	@Autowired
	private StringRedisTemplate stringRredisTemplate;
	
	@Autowired
    private EurekaClient eurekaClient;
	
	@Autowired
    private RestTemplate restTemplate;
	
	
	/**
	 * 将eureka上所有服务下的接口信息全部存入数据库
	 * 
	 * @Author caoxiubin
	 * @Create Date: 2019年4月22日 上午11:32:53
	 */
	public void initUrlToMysql() {
		logger.info("开始执行 initUrlToMysql() 方法，将接口数据持久化到 mysql 数据库中");
		try {
			
			List<SysUrl> urlList = new ArrayList<>();
			
			/*
			 * 第一步：从 eureka 注册中心获取所有服务的所有接口信息
			 */
			Applications applications = eurekaClient.getApplications();
			// 获取 eureka 上所有注册的服务实例
			List<Application> list = applications.getRegisteredApplications();
			SysUrl sysUrl = null;
			for (Application application : list) {
				// 通过swagger查询服务接口的接口来获取该服务节点下的所有服务接口明细
				String url = "http://" + application.getName() + "/scsj-cloud/v2/api-docs";
                String rsp = restTemplate.getForEntity(url, String.class).getBody();
                // 使用fastjson进行解析
                JSONObject apiObject = JSON.parseObject(rsp);
                String hostPort = apiObject.getString("host");
                String basePath = apiObject.getString("basePath");
                JSONObject pathsObject = apiObject.getJSONObject("paths");
                for (Map.Entry<String, Object> path : pathsObject.entrySet()) {
                	sysUrl = new SysUrl();
                	sysUrl.setUrlPath(hostPort+basePath+path.getKey());
                	JSONObject js = (JSONObject) path.getValue();
                	for (Map.Entry<String, Object> path1 : js.entrySet()) {
                		JSONObject js1 = (JSONObject) path1.getValue();
                		String summary = js1.getString("summary");
                		sysUrl.setUrlDesc(summary);
                    	urlList.add(sysUrl);
                	}
                }
			}
			
			logger.info("从 eureka 注册中心获取到的所有接口信息=====>"+JSONObject.toJSONString(urlList));
			
			/*
			 * 将所有接口信息持久化到数据库
			 */
			for (SysUrl sysUrlTemp : urlList) {
				//接口去重
				SysUrl sysUrl1 = this.urlMapper.selectByUrlPath(sysUrlTemp.getUrlPath());
				if(null == sysUrl1) {
					this.urlMapper.insert(sysUrlTemp);
				}
			}
			
		} catch (Exception e) {
			logger.error("缓存接口数据 initUrlToMysql() 方法出现异常：" + e);
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 服务启动时加载所有的url接口到redis数据库
	 * 存储思路: key:角色id+菜单id+接口值    value:接口值
	 * 
	 * @Author caoxiubin
	 * @Create Date: 2019年4月22日 上午11:32:53
	 */
	public void initUrlToRedis() {
		logger.info("开始执行 initUrlToRedis() 方法，将接口数据缓存到 redis 数据库中");
		try {
			//角色对应菜单对应的接口全量信息
			List<Map<String, String>> roleUrlInfo = new ArrayList<Map<String,String>>();
			
			Map<String, String> tempMap = null;
			List<Map<String, Object>> roleMenu = this.menuMapper.selectAllByRole();
			for (Map<String, Object> menuMap : roleMenu) {
				String roleId = menuMap.get("roleId").toString();
				String menuId = menuMap.get("menuId").toString();
				List<Map<String, Object>> menuUrl = this.urlMapper.selectAllByMenuId(Integer.valueOf(menuId));
				for (Map<String, Object> urlMap : menuUrl) {
					String urlPath = String.valueOf(urlMap.get("urlPath"));
					tempMap = Maps.newHashMap();
					tempMap.put("roleId", roleId);
					tempMap.put("menuId", menuId);
					tempMap.put("urlPath", urlPath);
					roleUrlInfo.add(tempMap);
				}
			}
			
			String urlPath = null;
			String urlKey = null;
			for (Map<String, String> map : roleUrlInfo) {
				
				String roleId = map.get("roleId");//角色ID
				String menuId = map.get("menuId");
				urlPath = map.get("urlPath").trim();//接口路径
				urlKey = (roleId + "_" +menuId+ "_" +urlPath).trim();
				
				// 判断key与value是否存在，如果不存在就直接存储
				if (stringRredisTemplate.opsForValue().setIfAbsent(urlKey, urlPath) == false) {
					stringRredisTemplate.opsForValue().set(urlKey, urlPath);
					logger.info("缓存的接口的KEY=====》"+urlKey);
				}
			}
			
			logger.info("接口缓存结束 ！");
			
		} catch (Exception e) {
			logger.error("缓存接口数据 initUrlToRedis() 方法出现异常："+e);
		}
	}
	
}
